package com.cmy.framework_base.basics.viewholder

import android.annotation.SuppressLint
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

/**
 * @name:
 *  BaseAdapter
 * @package:
 *  com.cmy.framework_base.viewholder
 * @date:
 *  2023/4/614:18
 * @author
 *    cmy
 * @description
 *
 */
open class BaseAdapter constructor(factoriesList: MutableList<BaseViewHolder.Factory>): RecyclerView.Adapter<BaseViewHolder>() {

    /**
     * 页面工厂，实现各类页面处理
     */
    private val factories: List<BaseViewHolder.Factory?> = factoriesList

    /**
     * type类型处理
     */
    private val type2ItemType: MutableMap<String, Int?> = mutableMapOf()


    /**
     * 数据源
     */
    private val dataSource: MutableList<IType> = mutableListOf()


    /**
     * 上下文，处理点击事件等交互问题问题
     */
    private var holderContext: HolderContext? = null


    /**
     * 初始化数据，初始化绑定对应的数据
     */
    constructor(dataSource: List<IType>, factoriesList: MutableList<BaseViewHolder.Factory>):this(factoriesList){
        this.dataSource.addAll(dataSource)
    }


    /**
     *在绑定数据的基础上，添加对应的上下文
     */
    constructor(holderContext: HolderContext, dataSource: List<IType>, factoriesList: MutableList<BaseViewHolder.Factory>):this(dataSource,factoriesList){
        this.holderContext = holderContext
    }


    init {
        for ( (index, factory) in factories.withIndex()){
            val type = factory?.getType()
            type?.let {
                val itemType : Int? = type2ItemType[it]
                if (itemType != null){
                    val currentFactory: String = factory.javaClass.name
                    val sameFactory = factories[itemType]?.javaClass?.name
                    throw RuntimeException("Same type found: $currentFactory and $sameFactory")
                }
                type2ItemType[it] = index

            }

        }
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        val targetFactory = factories[viewType] ?: throw  RuntimeException("No factory found with type equals $viewType")
        return targetFactory.onCreateViewHolder(holderContext,parent,viewType)
    }

    override fun getItemCount(): Int = dataSource.size


    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
        val itemData = dataSource[position]
        holder.onBindData(itemData)
    }


    override fun onBindViewHolder(
        holder: BaseViewHolder,
        position: Int,
        payloads: MutableList<Any>
    ) {
        if (payloads.isEmpty()){
            super.onBindViewHolder(holder, position, payloads)
        }else{
            val realPosition = holder.layoutPosition
            val data = dataSource[realPosition]
            holder.bindDataPayload(data,payloads)

        }
    }


    override fun getItemViewType(position: Int): Int {
        val iType = dataSource[position]
        val type = iType.getType()
        return type2ItemType[type]!!
    }

    override fun getItemId(position: Int): Long {
        return if (this.dataSource.isNotEmpty()) super.getItemId(position) else this.dataSource[position].hashCode().toLong()
    }

    //---------------------------------------------
    /**
     * 数据刷新
     *
     * @param dataSource 数据源
     */
    @SuppressLint("NotifyDataSetChanged")
    fun setDataSource(dataSource: MutableList<IType>?) {
        this.dataSource.clear()
        if (dataSource != null) {
            this.dataSource.addAll(dataSource)
        }
        notifyDataSetChanged()
    }

    /**
     * 数据添加
     *
     * @param dataSource 数据源
     */
    @SuppressLint("NotifyDataSetChanged")
    fun addDataSource(dataSource: MutableList<IType>?) {
        if (dataSource != null && dataSource.isNotEmpty()) {
            this.dataSource.addAll(dataSource)
            notifyDataSetChanged()
        }
    }


}
